﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using Wyse.Server.Logging;

namespace Wyse.Server.Base
{
    /// <summary>
    /// Builds message strings from objects
    /// </summary>
    public class MessageBuilder : IMessageProcessor
    {
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="consumer"></param>
        public MessageBuilder(IMessageConsumer consumer)
        {
            mConsumer = consumer;
        }

        /// <summary>
        /// Processes a message
        /// </summary>
        /// <param name="type"></param>
        /// <param name="data"></param>
        public void ProcessMessage(Message msg)
        {
            if (String.IsNullOrWhiteSpace(msg.Action))
                return;

            MemoryStream stream = new MemoryStream();
            var writer = JsonReaderWriterFactory.CreateJsonWriter(stream);

            // perform the message serialization

            writer.WriteStartElement("root");
            writer.WriteAttributeString("type", "object");

            writer.WriteElementString("action", msg.Action);

            if (msg.HasParameters)
            {
                try
                {
                    var serializer = MessageTypeMgr.GetSerializer(msg.Action);
                    if (serializer != null)
                    {
                        writer.WriteStartElement("params");

                        serializer.WriteObjectContent(writer, msg.Parameters);

                        writer.WriteEndElement();
                    }
                }
                catch (Exception e)
                {
                    Log.Error("Failed to serialize the parameters of message {0} ({1})", msg.Action, e.Message);
                }
            }

            writer.WriteEndElement();

            writer.Flush();

            byte[] messageBytes = stream.GetBuffer();
            mConsumer.ConsumeMessage(messageBytes, (int)stream.Length);
        }

        private IMessageConsumer mConsumer;
    }
}
